package cn.sc.summer.constant.model;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.annotation.JSONField;
import cn.sc.summer.constant.enums.ExceptionTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 类名：统一返回数据类型
 *
 * @author a-xin
 * @date 2022/8/25
 */
@Data
@Accessors(chain = true)
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 响应状态码
     */
    private Integer code;

    /**
     * 响应信息
     */
    private String message;

    /**
     * 响应状态码
     */
    private final String status = String.valueOf(IdUtil.getSnowflakeNextId());

    /**
     * 响应数据
     */
    private T data;

    /**
     * 成功响应信息
     */
    private static final String SUCCESS_INFO = "Operation successful!";
    private static final Integer SUCCESS_CODE = 200;

    /**
     * 失败相应信息
     */
    private static final String FAIL_INFO = "Operation is abnormal!";
    private static final Integer FAIL_CODE = 500;

    /**
     * 是否成功数据
     */
    @JSONField(serialize = false, deserialize = false)
    public Boolean isOK() {
        return this.code.equals(SUCCESS_CODE);
    }

    /**
     * 成功响应
     *
     * @return 无数据
     */
    public static Result<String> success() {
        return new Result<String>().setCode(SUCCESS_CODE)
                .setMessage(SUCCESS_INFO)
                .setData(SUCCESS_INFO);
    }

    /**
     * 成功响应带数据
     *
     * @param data 数据信息
     * @param <T>  数据类型
     * @return 返回值
     */
    public static <T> Result<T> success(T data) {
        return new Result<T>().setCode(SUCCESS_CODE)
                .setMessage(SUCCESS_INFO)
                .setData(data);
    }

    /**
     * 失败响应
     *
     * @return 返回值
     */
    public static Result<String> fail() {
        return new Result<String>().setCode(FAIL_CODE)
                .setMessage(FAIL_INFO)
                .setData(FAIL_INFO);
    }

    /**
     * 失败响应
     *
     * @param data 数据
     * @param <T>  数据类型
     * @return 返回值
     */
    public static <T> Result<T> fail(T data) {
        return new Result<T>().setCode(FAIL_CODE)
                .setMessage(FAIL_INFO)
                .setData(data);
    }

    /**
     * 失败响应
     *
     * @param message 失败信息
     * @param data    数据
     * @param <T>     数据类型
     * @return 返回值
     */
    public static <T> Result<T> fail(String message, T data) {
        return new Result<T>().setCode(FAIL_CODE)
                .setMessage(message)
                .setData(data);
    }

    /**
     * 失败响应
     *
     * @param code    失败代码
     * @param message 失败信息
     * @param data    数据
     * @param <T>     数据类型
     * @return 返回值
     */
    public static <T> Result<T> fail(Integer code, String message, T data) {
        return new Result<T>().setCode(code)
                .setMessage(message)
                .setData(data);
    }

    /**
     * 失败响应
     *
     * @param code    失败代码
     * @param message 失败信息
     * @return 返回值
     */
    public static <T> Result<T> fail(Integer code, String message) {
        return new Result<T>().setCode(code)
                .setMessage(message);
    }

    /**
     * 失败响应
     *
     * @param data              数据
     * @param exceptionTypeEnum 异常类型
     * @param <T>               数据类型
     * @return 返回值
     */
    public static <T> Result<T> fail(ExceptionTypeEnum exceptionTypeEnum, T data) {
        return new Result<T>().setCode(exceptionTypeEnum.getCode())
                .setMessage(exceptionTypeEnum.getMessage())
                .setData(data);
    }

    /**
     * 混滚异常
     *
     * @param message 异常信息
     * @return 返回值
     */
    public static <T> Result<T> fallback(String message) {
        return new Result<T>().setCode(FAIL_CODE)
                .setMessage(message);
    }

}
